home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d3 / rettig.arc / TRSOURCE.EXE / TOMONEY.C < prev    next >
C/C++ Source or Header  |  1990-10-22  |  6KB  |  181 lines

  1. /*********
  2. * Function: TOMONEY
  3. * By: Tom Rettig
  4. *
  5. * Placed in the public domain by Tom Rettig Associates, 10/22/1990.
  6. *
  7. * Syntax: TOMONEY( <expN> )
  8. * Return: <expC> "... dollars, and ... cents"
  9. *         Null string if passed invalid parameter.
  10. *         Asterisks if passed too large a number.
  11. * Note..: Rounds to two decimal places.
  12. *         Return string length varies in size.
  13. ********/
  14.  
  15. #include "trlib.h"
  16.  
  17. TRTYPE tomoney()
  18. {
  19.    static char *units[] =
  20.                  { "NO",
  21.                    "ONE",     "TWO",       "THREE",    "FOUR",     "FIVE",
  22.                    "SIX",     "SEVEN",     "EIGHT",    "NINE",     "TEN",
  23.                    "ELEVEN",  "TWELVE",    "THIRTEEN", "FOURTEEN", "FIFTEEN",
  24.                    "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"
  25.                  };
  26.    static char *teens[] =
  27.                  { " ", /*space*/
  28.                    "TEN",   "TWENTY",  "THIRTY", "FORTY",  "FIFTY",
  29.                    "SIXTY", "SEVENTY", "EIGHTY", "NINETY", " HUNDRED"
  30.                  };
  31.    static char *magnitude[] =
  32.                  { "", /*unused null*/
  33.                    " THOUSAND", " MILLION",     " BILLION",
  34.                    " TRILLION", " QUADRILLION", " QUINTILLION"
  35.                  };
  36.    static char *misc[] =
  37.                  { " and ",
  38.                     HYPHEN, ", ", " DOLLAR", " DOLLARS", " CENT", " CENTS"
  39.                  };
  40.    static char funcname[] = { "tomoney" };
  41.    char *aptr[PTRMAX];      /* array of pointers to word strings */
  42.    int  i, magi;            /* indexes into aptr[i] and magnitude[magi] arrays */
  43.    char *instr, *pos, *hold;       /* input pointers */
  44.    char *ret, *iret, *p;    /* output pointers */
  45.    int  allzero, zeroflag, iszero;   /* flags for zero values */
  46.    double temp;
  47.  
  48.    if ( PCOUNT == 1 && ISNUM(1) )
  49.    {
  50.       /* allocate memory for input and output buffers */
  51.       instr = _tr_allocmem( (unsigned) (INPUTMAX+1));
  52.       if ( !instr )
  53.       {
  54.          _retc( _tr_errmsgs(funcname,E_ALLOC) );
  55.          return;
  56.       }
  57.       ret = _tr_allocmem( (unsigned) (OUTPUTMAX+1));
  58.       if ( !ret )
  59.       {
  60.          _tr_freemem( instr,(unsigned)INPUTMAX+1);
  61.          _retc( _tr_errmsgs(funcname,E_ALLOC) );
  62.          return;
  63.       }
  64.       hold = instr;
  65.       /* internal "numeric to ascii": */
  66.       /* _tr_ntoa( (double)param, (int)len, (int)decimals, (char *)output ) */
  67.       temp = _parnd(1);
  68.       temp = _tr_fabs(temp);
  69.       _tr_ntoa( temp, INPUTMAX, DECIMAX, instr );
  70.  
  71.       if ( *instr == '*' )
  72.       {
  73.          _retc( NUM_OVRFLW );        /* return asterisks if overflow */
  74.          _tr_freemem( hold,(unsigned)INPUTMAX+1); /* free instr */
  75.          _tr_freemem( ret,(unsigned)OUTPUTMAX+1);
  76.          return;
  77.       }
  78.  
  79.       /* point to first digit, and find decimal point */
  80.       while ( *instr == SPACEC)
  81.          instr++;
  82.       pos = instr;
  83.       while ( *pos!=DECPOINT && *pos )
  84.          pos++;
  85.  
  86.       /* set pointers to each word, going from least significant digit to most */
  87.       i = 0;
  88.       if ( pos[2] == '1' && pos[1] == ZEROC )    /* one cent */
  89.          aptr[i++] = misc[5];       /* " CENT" */
  90.       else
  91.          aptr[i++] = misc[6];       /* " CENTS" */
  92.  
  93.       /* cents digits */
  94.       if ( pos[2] == ZEROC && pos[1] == ZEROC )  /* zero cents */
  95.          aptr[i++] = units[0];      /* "NO" */
  96.       else
  97.          aptr[i++] = pos+1;         /* cents string of digits */
  98.  
  99.       /* separate dollars from cents */
  100.       aptr[i++] = misc[0];          /* " and " */
  101.  
  102.       if ( pos[-1] == '1' && pos == instr+1 )       /* one dollar */
  103.          aptr[i++] = misc[3];       /* " DOLLAR" */
  104.       else
  105.          aptr[i++] = misc[4];       /* " DOLLARS" */
  106.  
  107.       if ( pos[-1] == ZEROC && pos == instr+1 )     /* zero dollars */
  108.          aptr[i++] = units[0];      /* "NO" */
  109.       else
  110.       {
  111.          allzero  = TRUE;       /* scope of all magnitudes */
  112.          zeroflag = TRUE;       /* scope of previous and current magnitudes */
  113.          iszero   = TRUE;       /* scope of current magnitude only */
  114.  
  115.          /* loop through each magnitude of three digits until done */
  116.          for ( magi=0; pos>instr; pos+=(-3), magi++ )
  117.          {
  118.             /* zero flag settings */
  119.             if ( zeroflag && !iszero )
  120.                zeroflag = allzero = FALSE;
  121.             iszero = ( pos[-1]==ZEROC && pos[-2]==ZEROC && pos[-3]==ZEROC );
  122.             if ( !zeroflag && iszero )
  123.                zeroflag = TRUE;
  124.  
  125.             /* magnitude */
  126.             if ( magi && !iszero )
  127.             {
  128.                if ( !zeroflag || !allzero )
  129.                   aptr[i++] = misc[2];      /* magnitude delimiter */
  130.                aptr[i++] = magnitude[magi];
  131.             }
  132.  
  133.             /* units and teens values */
  134.             if ( pos[-1] > ZEROC )
  135.             {
  136.                if ( (pos[-2] == ZEROC || pos < instr+2) )
  137.                   aptr[i++] = units[ ONES(pos) ];
  138.                else if ( pos[-2] == '1' )
  139.                   aptr[i++] = units[ (TENS(pos)*10) + ONES(pos) ];
  140.                else if ( pos[-2] > '1' && pos >= instr+2 )
  141.                {
  142.                   aptr[i++] = units[ ONES(pos) ];
  143.                   aptr[i++] = misc[1];      /* HYPHEN */
  144.                   aptr[i++] = teens[ TENS(pos) ];
  145.                }
  146.             }
  147.             else if ( pos[-2] > ZEROC && pos >= instr+2 )
  148.                aptr[i++] = teens[ TENS(pos) ];
  149.  
  150.             /* hundreds value */
  151.             if ( pos[-3] > ZEROC && pos >= instr+2 )
  152.             {
  153.                if ( pos[-2] > ZEROC || pos[-1] > ZEROC )
  154.                   aptr[i++] = teens[0];     /* " " */
  155.                aptr[i++] = teens[10];       /* " HUNDRED" */
  156.                aptr[i++] = units[ HUNS(pos) ];
  157.             }
  158.          } /* endwhile */
  159.       } /* endif */
  160.  
  161.       /* concatenate word pointers into one string and store in output buffer */
  162.       iret = ret;
  163.       i--;
  164.       while ( i >= 0 )
  165.       {
  166.          p = aptr[i--];
  167.          while ( *p )
  168.             *iret++ = *p++;
  169.       }
  170.       *iret = NULLC;
  171.  
  172.       _retc( ret );
  173.       _tr_freemem( hold,(unsigned)INPUTMAX+1 ); /*free instr*/
  174.       _tr_freemem( ret,(unsigned)OUTPUTMAX+1 );
  175.    }
  176.    else
  177.       _retc( _tr_errmsgs(funcname,E_SYNTAX) );
  178. }
  179. /* eof */
  180.  
  181.